package com.ecommerce.product.service.impl;

import com.ecommerce.product.dto.CategoryCreateRequest;
import com.ecommerce.product.dto.CategoryResponse;
import com.ecommerce.product.dto.CategoryUpdateRequest;
import com.ecommerce.product.entity.Category;
import com.ecommerce.product.exception.BusinessException;
import com.ecommerce.product.repository.CategoryRepository;
import com.ecommerce.product.service.CategoryService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 分类服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class CategoryServiceImpl implements CategoryService {

    private final CategoryRepository categoryRepository;

    @Override
    public List<CategoryResponse> getAllVisibleCategories() {
        log.info("获取所有可见分类");
        
        List<Category> categories = categoryRepository.findByDeleteStatusOrderBySortOrderAsc(0);
        
        List<CategoryResponse> categoryResponses = categories.stream()
                .filter(Category::getIsVisible)
                .map(this::convertToResponse)
                .collect(Collectors.toList());
        
        log.info("获取到 {} 个可见分类", categoryResponses.size());
        return categoryResponses;
    }

    @Override
    public List<CategoryResponse> getAllCategories() {
        log.info("获取所有分类（包括已删除的）");
        
        List<Category> categories = categoryRepository.findAllByOrderBySortOrderAsc();
        
        List<CategoryResponse> categoryResponses = categories.stream()
                .map(this::convertToResponse)
                .collect(Collectors.toList());
        
        log.info("获取到 {} 个分类", categoryResponses.size());
        return categoryResponses;
    }

    @Override
    public CategoryResponse getCategoryById(Long id) {
        log.info("根据ID获取分类: {}", id);
        
        Category category = categoryRepository.findByIdAndDeleteStatus(id, 0)
                .orElseThrow(() -> new BusinessException("分类不存在或已删除"));
        
        return convertToResponse(category);
    }

    @Override
    @Transactional
    public CategoryResponse createCategory(CategoryCreateRequest request) {
        log.info("创建分类: {}", request.getName());
        
        // 检查分类名称唯一性
        categoryRepository.findByNameAndDeleteStatus(request.getName(), 0)
                .ifPresent(category -> {
                    throw new BusinessException("分类名称已存在");
                });
        
        // 验证父分类
        if (request.getParentId() != null) {
            Category parentCategory = categoryRepository.findByIdAndDeleteStatus(request.getParentId(), 0)
                    .orElseThrow(() -> new BusinessException("父分类不存在或已删除"));
        }
        
        Category category = new Category();
        category.setName(request.getName());
        category.setDescription(request.getDescription());
        category.setParentId(request.getParentId());
        category.setSortOrder(request.getSortOrder() != null ? request.getSortOrder() : 0);
        category.setIsVisible(request.getIsVisible() != null ? request.getIsVisible() : true);
        category.setDeleteStatus(0);
        category.setCreatedAt(LocalDateTime.now());
        category.setUpdatedAt(LocalDateTime.now());
        
        Category savedCategory = categoryRepository.save(category);
        log.info("分类创建成功: {} (ID: {})", savedCategory.getName(), savedCategory.getId());
        
        return convertToResponse(savedCategory);
    }

    @Override
    @Transactional
    public CategoryResponse updateCategory(Long id, CategoryUpdateRequest request) {
        log.info("更新分类: {}", id);
        
        Category category = categoryRepository.findByIdAndDeleteStatus(id, 0)
                .orElseThrow(() -> new BusinessException("分类不存在或已删除"));
        
        // 检查分类名称唯一性（排除当前分类）
        categoryRepository.findByNameAndDeleteStatus(request.getName(), 0)
                .ifPresent(existingCategory -> {
                    if (!existingCategory.getId().equals(id)) {
                        throw new BusinessException("分类名称已存在");
                    }
                });
        
        // 验证父分类
        if (request.getParentId() != null) {
            Category parentCategory = categoryRepository.findByIdAndDeleteStatus(request.getParentId(), 0)
                    .orElseThrow(() -> new BusinessException("父分类不存在或已删除"));
            
            // 检查是否尝试将自身设为父分类
            if (request.getParentId().equals(id)) {
                throw new BusinessException("分类不能将自身设为父分类");
            }
            
            // 检查循环引用
            if (categoryRepository.countCircularReference(id, request.getParentId()) > 0) {
                throw new BusinessException("不能创建循环的父子分类关系");
            }
        }
        
        category.setName(request.getName());
        category.setDescription(request.getDescription());
        category.setParentId(request.getParentId());
        category.setSortOrder(request.getSortOrder());
        category.setIsVisible(request.getIsVisible());
        
        Category updatedCategory = categoryRepository.save(category);
        log.info("分类更新成功: {} (ID: {})", updatedCategory.getName(), updatedCategory.getId());
        
        return convertToResponse(updatedCategory);
    }

    @Override
    @Transactional
    public void deleteCategory(Long id) {
        log.info("删除分类: {}", id);
        
        Category category = categoryRepository.findByIdAndDeleteStatus(id, 0)
                .orElseThrow(() -> new BusinessException("分类不存在或已删除"));
        
        // 检查是否有子分类
        long childCount = categoryRepository.countByParentIdAndDeleteStatus(id, 0);
        if (childCount > 0) {
            throw new BusinessException("该分类下存在子分类，不能删除");
        }
        
        // 逻辑删除
        category.setDeleteStatus(1);
        category.setDeletedAt(LocalDateTime.now());
        category.setIsVisible(false);
        
        categoryRepository.save(category);
        log.info("分类删除成功: {} (ID: {})", category.getName(), category.getId());
    }

    @Override
    public List<CategoryResponse> getCategoriesByParentId(Long parentId) {
        log.info("获取父分类下的子分类: {}", parentId);
        
        List<Category> categories;
        if (parentId == null) {
            // 获取顶级分类
            categories = categoryRepository.findByParentIdAndDeleteStatusOrderBySortOrderAsc(null, 0);
        } else {
            // 验证父分类是否存在
            categoryRepository.findByIdAndDeleteStatus(parentId, 0)
                    .orElseThrow(() -> new BusinessException("父分类不存在或已删除"));
            
            categories = categoryRepository.findByParentIdAndDeleteStatusOrderBySortOrderAsc(parentId, 0);
        }
        
        List<CategoryResponse> categoryResponses = categories.stream()
                .map(this::convertToResponse)
                .collect(Collectors.toList());
        
        log.info("获取到 {} 个子分类", categoryResponses.size());
        return categoryResponses;
    }

    /**
     * 转换为响应DTO
     * @param category 分类实体
     * @return 分类响应DTO
     */
    private CategoryResponse convertToResponse(Category category) {
        CategoryResponse response = new CategoryResponse();
        response.setId(category.getId());
        response.setName(category.getName());
        response.setDescription(category.getDescription());
        response.setParentId(category.getParentId());
        response.setSortOrder(category.getSortOrder());
        response.setIsVisible(category.getIsVisible());
        response.setCreatedAt(category.getCreatedAt());
        response.setUpdatedAt(category.getUpdatedAt());
        response.setDeleteStatus(category.getDeleteStatus());
        response.setDeletedAt(category.getDeletedAt());
        return response;
    }
}